﻿
#if !(UNITY_STANDALONE_WIN || UNITY_STANDALONE_LINUX || UNITY_STANDALONE_OSX || STEAMWORKS_WIN || STEAMWORKS_LIN_OSX)
#define DISABLESTEAMWORKS
#endif
using Mirror;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Internal;

public class FlyItem: NetworkBehaviour
{
    [SyncVar]
    public Vector3 FlyDirection = new Vector3(0, 1, 0);
    public float Life = 1;
    public float FlyVelocity = 0;
    [SyncVar]
    public float CurFlyVelocity = 1;

    public float Damage = 1;
    public string WeaponClassName = "";
    public bool FriendsHurt = true;
    [SyncVar]
    public float m_ExplotionScale = 1;
    [SyncVar(hook = nameof(OnPositionChanged))]
    public Vector3 m_Position;
    public Vector3 m_PerviusPosition;
    [NonSerialized, SyncVar(hook = nameof(OnRotationChanged))]
    public Quaternion m_Rotation = Quaternion.identity;
    public Quaternion m_PerviusRotation;
    [SyncVar(hook = nameof(OnScaleChanged))]
    public Vector3 m_Scale = Vector3.one;
    public Vector3 m_PerviusScale;

    public Weapon.DamageType WeaponType;
    public Weapon m_Weapon;
    public WeaponSlot m_Slot;
    public ParticleSystem m_BoomEffect;
    public Callback OnBoomCallback;
    public bool Death { set { m_Death = value; } get {return m_Death; } }
    [SyncVar]
    bool m_Death;
    public GameObject Ship {
        set { 
            m_Ship = value;
            if(m_Ship)
                m_Influence = m_Ship.GetComponent<Ship>().m_ShipStruct.Influence; 
                }
        get { return m_Ship; }
            }
    public GameObject m_Ship;
    public string m_Influence;

    public virtual void Awake()
    {
    }

    public virtual void Start()
    {
    }

    public virtual void Update()
    {
        if (Death)
            return;
        UpdateNetwork();
        if (UtilsGame.IsOnline() && !UtilsGame.IsServer(gameObject))
        {
            return;
        }
        if (Life < 0)
        {
            OnRangeMax();
        }
    }
    float m_NetworkUpdateTimeCount = 0;
    float m_NetworkUpdateTimeCountMax = 0.1f;
    public void UpdateNetwork()
    {
        if (!UtilsGame.IsOnline())
            return;
        if (!UtilsGame.IsServer(gameObject))
        {
            //transform.rotation = Quaternion.FromToRotation(Vector3.up, FlyDirection);
            var moveOffset = FlyDirection * (CurFlyVelocity * Time.deltaTime);
            transform.position += moveOffset;
            //transform.position = Vector3.Lerp(transform.position, m_Position, Mathf.Clamp(Time.deltaTime * 10, 0, 1));
            transform.rotation = Quaternion.Lerp(transform.rotation, m_Rotation, Mathf.Clamp(Time.deltaTime * 10, 0, 1));
            transform.localScale = Vector3.Lerp(transform.localScale, m_Scale, Mathf.Clamp(Time.deltaTime * 10, 0, 1));

            return;
        }

        m_NetworkUpdateTimeCount += Time.deltaTime;
        if (m_NetworkUpdateTimeCount < m_NetworkUpdateTimeCountMax)
            return;
        m_NetworkUpdateTimeCount = 0;

        m_Position = transform.position;
        m_Rotation = transform.rotation;
        m_Scale = transform.localScale;
    }

    void OnPositionChanged(Vector3 _Old, Vector3 _New)
    {
        if (m_Death)
            return;
        m_PerviusPosition = _Old;
        m_Position = _New;
        transform.position = m_Position;
        //if ((transform.position - m_Position).magnitude > 1)
        //{
        //    transform.position = m_Position;
        //}

    }
    void OnRotationChanged(Quaternion _Old, Quaternion _New)
    {
        if (m_Death)
            return;
        m_PerviusRotation = _Old;
        m_Rotation = _New;
    }
    void OnScaleChanged(Vector3 _Old, Vector3 _New)
    {
        if (m_Death)
            return;
        m_PerviusScale = _Old;
        m_Scale = _New;
    }

    virtual protected void OnTriggerEnter2D(Collider2D collision)
    {
        if (UtilsGame.IsOnline() && !UtilsGame.IsServer(gameObject))
        {
            return;
        }
        //  如果没开友伤则穿过队友
        if (!FriendsHurt)
        {
            Ship ship = UtilsGame.FindShip(collision.gameObject);
            if(ship && !InfluenceMG.get().isHostile(m_Influence,ship.m_ShipStruct.m_Influence))
                return;
        }
        if(CalcDamage(collision, m_Ship, Damage, WeaponType))
        {
            OnBoom();
        }
    }

    virtual public void InitParameter(Vector3 position, Vector3 direction, float flyVelocity, float range, float damge, string weaponClassName, Weapon.DamageType dameageType, Ship ship,Weapon weapon )
    {
        clean();
        FlyDirection = direction;
        transform.position = position;
        FlyVelocity = flyVelocity;
        Life = range;
        WeaponClassName = weaponClassName;
        WeaponType = dameageType;
        if(ship)
            Ship = ship.gameObject;
        Damage = damge;
        m_Weapon = weapon;
        CurFlyVelocity = FlyVelocity;
    }

    public static bool CalcDamage(Collider2D collision, GameObject selfShip, float damage, Weapon.DamageType damageType)
    {
        bool ret = false;
        var obj = collision.gameObject;

        while (obj)
        {
            if (selfShip == obj)
                return ret;
            var parentTransform = obj.transform.parent;
            if (!parentTransform)
                break ;
            obj = parentTransform.gameObject;
        }
        obj = collision.gameObject;
        Ship ship = obj.GetComponent<Ship>();

        ShildFunction shild = obj.GetComponent<ShildFunction>();
        MissileFunction missile = obj.GetComponent<MissileFunction>();
        UAVFunction uav = obj.GetComponent<UAVFunction>();

        if (ship)
        {
            ret = true;
            if(ship.Boom(damage, damageType))
            {
                CalcAchievement(selfShip, obj);
            }
        }
        else if (shild)
        {
            ret = true;
            shild.Boom(damage, damageType);
        }
        else if (missile)
        {
            ret = true;
            missile.Boom(damage, damageType);
        }
        else if (uav && uav.m_Ship != selfShip)
        {
            ret = true;
            uav.Boom(damage, damageType);
        }
        return ret;
    }

    protected virtual void OnDestroy()
    {
    }
    protected virtual void OnBoom()
    {
        if (UtilsGame.IsOnline() && UtilsGame.IsServer(gameObject))
            RpcOnBoomEffect(transform.position);
        BoomEffect();
        if (OnBoomCallback != null)
            OnBoomCallback();
        if(!BulletPool.get().Recycle(gameObject))
        {
            Destroy(this.gameObject);
        }
    }
    protected virtual void BoomEffect()
    {
        BoomEffect(transform.position);
    }
    protected virtual void BoomEffect(Vector3 position)
    {
        if (m_BoomEffect)
        {
            var effect = Instantiate(m_BoomEffect);
            SetParticleScale(effect.gameObject, m_ExplotionScale);
            effect.transform.SetParent(BulletPool.get().m_BulletPoolObj.transform);
            effect.transform.position = position;
            effect.Play();
            GameObject.Destroy(effect.gameObject, effect.main.duration);
        }
    }
    protected virtual void OnRangeMax()
    {
        if (!BulletPool.get().Recycle(gameObject))
        {
            Death = true;
            Destroy(gameObject);
        }
    }
    public virtual void clean()
    {

    }
    public void SetParticleScale(GameObject obj, float scale)
    {
        var particle = obj.GetComponent<ParticleSystem>();
        if (particle)
        {
            particle.transform.localScale *= scale;
            var main = particle.main;
            if(!particle.isPlaying)
            {
                main.duration *= scale;
                var colorS = main.startColor;
                var color = colorS.color;
                color.a *= scale;
                colorS.color = color;
                main.startColor = colorS;
            }
            var f =  main.startLifetime;
            f.constant *= scale;
            f.constantMin *= scale;
            f.constantMax *= scale;
        }

        var audio = obj.GetComponent<AudioSource>();
        if (audio)
            audio.volume *= scale;
        for (int i=0; i<obj.transform.childCount; ++i)
        {
            SetParticleScale(obj.transform.GetChild(i).gameObject, scale);
        }
    }

    static void CalcAchievement(GameObject self, GameObject other)
    {
#if !DISABLESTEAMWORKS
        if (self == null || other == null)
            return;
        var selfShipCom = self.GetComponent<Ship>();
        var otehrShip = other.GetComponent<Ship>();
        if (selfShipCom &&  InfluenceMG.get().IsPlayer(selfShipCom.m_ShipStruct.m_Influence))
        {
            if (UtilsGame.IsSteamMG())
            {

                if (InfluenceMG.get().isHostile(selfShipCom.m_ShipStruct.m_Influence, otehrShip.m_ShipStruct.m_Influence))
                {
                    int killNumber = 0;
                    if (Steamworks.SteamUserStats.GetStat("enemy_keil_count", out killNumber))
                    {
                        Steamworks.SteamUserStats.SetStat("enemy_keil_count", (++killNumber));
                        if (killNumber >= 100)
                            Steamworks.SteamUserStats.SetAchievement("HUNDRED_KILLER");
                        if (killNumber >= 1000)
                            Steamworks.SteamUserStats.SetAchievement("THOUSAND_KILLER");
                    }
                    Steamworks.SteamUserStats.StoreStats();
                }
                else
                {
                    int killNumber = 0;
                    if (Steamworks.SteamUserStats.GetStat("team_keil_count", out killNumber))
                    {
                        Steamworks.SteamUserStats.SetStat("team_keil_count", (++killNumber));
                        if (killNumber >= 1)
                            Steamworks.SteamUserStats.SetAchievement("TEAM_KILLER1");
                        if (killNumber >= 1000)
                            Steamworks.SteamUserStats.SetAchievement("TEAN_KILLER100");
                    }
                    Steamworks.SteamUserStats.StoreStats();
                }
            }
        }
#endif
    }
    
    #region Command
    [ClientRpc]
    protected void RpcOnBoomEffect(Vector3 position)
    {
        m_Death = true;
        transform.position = new Vector3(0, 1111111111, 0);
        BoomEffect(position);
    }
    [ClientRpc]
    public void RpcOnDeath()
    {
        transform.position = new Vector3(0, 1111111111, 0);
        m_Death = true;
    }
    #endregion
}